home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 98 / Skunkware 98.iso / src / mail / pine3.96.tar.gz / pine3.96.tar / pine3.96 / imap / non-ANSI / c-client / sm_unix.c < prev    next >
C/C++ Source or Header  |  1996-05-15  |  6KB  |  185 lines

  1. /*
  2.  * Program:    Subscription Manager (Unix based)
  3.  *
  4.  * Author:    Mark Crispin
  5.  *        Networks and Distributed Computing
  6.  *        Computing & Communications
  7.  *        University of Washington
  8.  *        Administration Building, AG-44
  9.  *        Seattle, WA  98195
  10.  *        Internet: MRC@CAC.Washington.EDU
  11.  *
  12.  * Date:    19 November 1992
  13.  * Last Edited:    15 May 1996
  14.  *
  15.  * Copyright 1996 by the University of Washington
  16.  *
  17.  *  Permission to use, copy, modify, and distribute this software and its
  18.  * documentation for any purpose and without fee is hereby granted, provided
  19.  * that the above copyright notice appears in all copies and that both the
  20.  * above copyright notice and this permission notice appear in supporting
  21.  * documentation, and that the name of the University of Washington not be
  22.  * used in advertising or publicity pertaining to distribution of the software
  23.  * without specific, written prior permission.  This software is made
  24.  * available "as is", and
  25.  * THE UNIVERSITY OF WASHINGTON DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED,
  26.  * WITH REGARD TO THIS SOFTWARE, INCLUDING WITHOUT LIMITATION ALL IMPLIED
  27.  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, AND IN
  28.  * NO EVENT SHALL THE UNIVERSITY OF WASHINGTON BE LIABLE FOR ANY SPECIAL,
  29.  * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  30.  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, TORT
  31.  * (INCLUDING NEGLIGENCE) OR STRICT LIABILITY, ARISING OUT OF OR IN CONNECTION
  32.  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  33.  *
  34.  */
  35.  
  36.  
  37. #include "mail.h"
  38. #include "osdep.h"
  39. #include <sys/stat.h>
  40. #include "misc.h"
  41.  
  42. #define SUBSCRIPTIONFILE(t) sprintf (t,"%s/.mailboxlist",myhomedir ())
  43.  
  44. /* Subscribe to mailbox
  45.  * Accepts: mailbox name
  46.  * Returns: T on success, NIL on failure
  47.  */
  48.  
  49. long sm_subscribe (mailbox)
  50.     char *mailbox;
  51. {
  52.   int fd;
  53.   char *s,*t,*txt,tmp[MAILTMPLEN],tmpx[MAILTMPLEN];
  54.   struct stat sbuf;
  55.   long ret = T;
  56.   if (*mailbox == '/') {    /* coerce absolute file paths */
  57.     int i = strlen (s = myhomedir ());
  58.     if (!strncmp (mailbox,s,i) && mailbox[i] == '/') {
  59.       sprintf (tmpx,"~%s",mailbox + i);
  60.       mailbox = tmpx;        /* set as name to subscribe */
  61.     }
  62.   }
  63.   SUBSCRIPTIONFILE (tmp);    /* open subscription database */
  64.   if ((fd = open (tmp,O_RDWR|O_CREAT,
  65.           (int) mail_parameters (NIL,GET_SUBPROTECTION,NIL))) >= 0) {
  66.     flock (fd,LOCK_EX);        /* wait for exclusive access */
  67.     fstat (fd,&sbuf);        /* get file size and read data */
  68.     read (fd,s = txt = (char *) fs_get (sbuf.st_size + 1),sbuf.st_size);
  69.     s[sbuf.st_size] = '\0';    /* tie off string */
  70.     while (t = strchr (s,'\n')){/* for each line in database */
  71.       *t++ = '\0';        /* tie off string */
  72.       if (strcmp (s,mailbox)) s = t;
  73.       else {            /* oops, it's subscribed */
  74.     sprintf (tmp,"Already subscribed to mailbox %s",mailbox);
  75.     mm_log (tmp,ERROR);
  76.     ret = NIL;
  77.     break;
  78.       }
  79.     }
  80.     if (ret) {            /* append to end of file if OK */
  81.       lseek (fd,sbuf.st_size,L_SET);
  82.       sprintf (tmp,"%s\n",mailbox);
  83.       write (fd,tmp,strlen (tmp));
  84.       fsync (fd);        /* drop changes */
  85.     }
  86.     flock (fd,LOCK_UN);        /* release lock */
  87.     close (fd);            /* close off file */
  88.     fs_give ((void **) &txt);    /* free database */
  89.   }
  90.   else {
  91.     mm_log ("Can't create subscription database",ERROR);
  92.     ret = NIL;
  93.   }
  94.   return ret;            /* all done */
  95. }
  96.  
  97. /* Unsubscribe from mailbox
  98.  * Accepts: mailbox name
  99.  * Returns: T on success, NIL on failure
  100.  */
  101.  
  102. long sm_unsubscribe (mailbox)
  103.     char *mailbox;
  104. {
  105.   int fd;
  106.   char *s,*t,*txt,*end,tmp[MAILTMPLEN],tmpx[MAILTMPLEN];
  107.   struct stat sbuf;
  108.   long ret = NIL;
  109.   if (*mailbox == '/') {    /* coerce absolute file paths */
  110.     int i = strlen (s = myhomedir ());
  111.     if (!strncmp (mailbox,s,i) && mailbox[i] == '/') {
  112.       sprintf (tmpx,"~%s",mailbox + i);
  113.       mailbox = tmpx;        /* set as name to subscribe */
  114.     }
  115.   }
  116.   SUBSCRIPTIONFILE (tmp);    /* open subscription database */
  117.   if ((fd = open (tmp,O_RDWR,NIL)) >= 0) {
  118.     flock (fd,LOCK_EX);        /* wait for exclusive access */
  119.     fstat (fd,&sbuf);        /* get file size and read data */
  120.     read (fd,s = txt = (char *) fs_get (sbuf.st_size + 1),sbuf.st_size);
  121.                 /* tie off string */
  122.     *(end = s + sbuf.st_size) = '\0';
  123.     while (t = strchr (s,'\n')){/* for each line in database */
  124.       *t++ = '\0';        /* temporarily tie off string */
  125.       if (strcmp (s,mailbox)) {    /* match? */
  126.     t[-1] = '\n';        /* no, restore newline */
  127.     s = t;            /* try next subscription */
  128.       }
  129.       else {            /* cancel subscription */
  130.     if (t != end) memcpy (s,t,1 + end - t);
  131.     end -= t - s;        /* calculate new end of database */
  132.     ret = T;        /* note cancelled a subscription */
  133.       }
  134.     }
  135.     if (ret) {            /* found any? */
  136.       lseek (fd,0,L_SET);    /* yes, seek to start of file and write new */
  137.       if (end != txt) write (fd,txt,end - txt);
  138.       ftruncate (fd,end - txt);    /* tie off file */
  139.       fsync (fd);        /* drop changes */
  140.     }
  141.     else {            /* subscription not found */
  142.       sprintf (tmp,"Not subscribed to mailbox %s",mailbox);
  143.       mm_log (tmp,ERROR);    /* error if at end */
  144.     }
  145.     flock (fd,LOCK_UN);        /* release lock */
  146.     close (fd);            /* close off file */
  147.     fs_give ((void **) &txt);    /* free database */
  148.   }
  149.   else {
  150.     mm_log ("No subscriptions",ERROR);
  151.     ret = NIL;
  152.   }
  153.   return ret;            /* all done */
  154. }
  155.  
  156. /* Read subscription database
  157.  * Accepts: pointer to subscription database handle (handle NIL if first time)
  158.  * Returns: character string for subscription database or NIL if done
  159.  * Note - uses strtok() mechanism
  160.  */
  161.  
  162. char *sm_read (sdb)
  163.     void **sdb;
  164. {
  165.   int fd;
  166.   char *s,*t,tmp[MAILTMPLEN];
  167.   struct stat sbuf;
  168.   if (!*sdb) {            /* first time through? */
  169.     SUBSCRIPTIONFILE (tmp);    /* open subscription database */
  170.     if ((fd = open (tmp,O_RDWR,NIL)) >= 0) {
  171.       flock (fd,LOCK_SH);    /* let others know we're here */
  172.       fstat (fd,&sbuf);        /* get file size and read data */
  173.       read (fd,s = (char *) (*sdb = fs_get (sbuf.st_size + 1)),sbuf.st_size);
  174.       flock (fd,LOCK_UN);    /* release lock */
  175.       close (fd);        /* close file */
  176.       s[sbuf.st_size] = '\0';    /* tie off string */
  177.       if (t = strtok (s,"\n")) return t;
  178.     }
  179.   }
  180.                 /* subsequent times through database */
  181.   else if (t = strtok (NIL,"\n")) return t;
  182.   fs_give (sdb);        /* free database */
  183.   return NIL;            /* all done */
  184. }
  185.